﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LaxFriedrichsModel
{
    public class Equatios
    {
        float t;

        public float T
        {
            get { return t; }
            set { t = value; }
        }
        float x;

        public float X
        {
            get { return x; }
            set { x = value; }
        }
        int numT;

        public int NumT
        {
            get { return numT; }
            set { numT = value; }
        }
        int numX;

        public int NumX
        {
            get { return numX; }
            set { numX = value; }
        }
        float dt;

        public float Dt
        {
            get { return dt; }
            set { dt = value; }
        }
        float dx;

        public float Dx
        {
            get { return dx; }
            set { dx = value; }
        }

        U[] uArr;

        public U[] UArr
        {
            get { return uArr; }
            set { uArr = value; }
        }
        F[] fArr;
        internal F[] FArr
        {
            get { return fArr; }
            set { fArr = value; }
        }

        public Equatios(int _numX)
        {
            fArr = new F[_numX];
            uArr = new U[_numX];
            numX = _numX;
        }

        public U[] GetLayer(int layerNumber)
        {
            F[] tempFArr = new F[numX];
            U[] tempUArr = uArr;

            for (int i = 0; i < numX; i++)
                tempFArr[i] = new F();

            if (layerNumber < 0)
                layerNumber = 0;
            if (layerNumber > numT)
                layerNumber = numT;

            
            for (int i = 0; i < layerNumber; i++)
            {
                tempUArr = SetRows(tempUArr);
                
                tempFArr = GetFArrFromUarr(tempUArr);
                tempUArr = NextLayer(tempUArr, tempFArr);
                //Console.WriteLine(tempUArr.ToString());
                foreach (var u in tempUArr)
                    Console.WriteLine(u.ToString());   
                Console.WriteLine("___________");
            }

            return tempUArr;

        }

        private U[] SetRows(U[] tempUArr)
        {
            U[] uArr = tempUArr;
            for (int i = 0; i < numX; i++)
                uArr[i].SetRows();
            return uArr;
        }

        private U[] NextLayer(U[] tempUArr, F[] tempFArr)
        {
            U[] uArr = Predictor(tempUArr, tempFArr);

            return uArr;

        }

        private U[] Predictor(U[] tempUArr, F[] tempFArr)
        {
            U[] uArr = tempUArr;
            uArr[0] = tempUArr[0];
            uArr[numX - 1] = tempUArr[numX - 1];
            for (int i = 1; i < numX - 1; i++)
            {
                uArr[i].Row1 = tempUArr[i].Row1 - dt / (2 * dx) * (tempFArr[i + 1].Row1 - tempFArr[i - 1].Row1);
                uArr[i].Row2 = tempUArr[i].Row2 - dt / (2 * dx) * (tempFArr[i + 1].Row2 - tempFArr[i - 1].Row2);
                uArr[i].Row3 = tempUArr[i].Row3 - dt / (2 * dx) * (tempFArr[i + 1].Row3 - tempFArr[i - 1].Row3);
                uArr[i].UpdateValues();
            }

            return uArr;
        }
        
        public F[] GetFArrFromUarr(U[] uArr)
        {
            F[] tempFArr = new F[numX];
            for (int j = 0; j < numX; j++)
            {
                tempFArr[j] = new F();
                tempFArr[j].SetRowsByU(uArr[j]);
            }
            return tempFArr;
        }
    }
}
